package com.topnav.mc.base;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.js.lib.cache.SysCache;
import com.topnav.mc.admin.entity.Organization;
import com.topnav.mc.admin.security.PermissionGrade;
import com.topnav.mc.common.Constant;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

public abstract class CommViewServiceImpl <M extends BaseMapper<T>, T> implements ICommViewService<T> {
    protected Log log = LogFactory.getLog(getClass());
    @Autowired
    private SysCache sysCache;
    @Autowired
    protected M baseMapper;

    @Override
    public M getBaseMapper() {
        return baseMapper;
    }
    /** 反射对象获取泛型  entity 类*/

    protected Class<?> entityClass = (Class<T>) ReflectionKit.getSuperClassGenericType(getClass(), 1);
    protected Class<?> mapperClass = (Class<T>) ReflectionKit.getSuperClassGenericType(getClass(), 0);

    /**
     * 获取mapperStatementId
     *
     * @param sqlMethod 方法名
     * @return 命名id
     * @since 3.4.0
     */
    protected String getSqlStatement(SqlMethod sqlMethod) {
        return SqlHelper.getSqlStatement(mapperClass, sqlMethod);
    }

    @Override
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdate(T entity) {
        return false;
    }

    @Override
    public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
        if (throwEx) {
            return baseMapper.selectOne(queryWrapper);
        }
        return SqlHelper.getObject(log, baseMapper.selectList(queryWrapper));
    }

    @Override
    public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
        return SqlHelper.getObject(log, baseMapper.selectMaps(queryWrapper));
    }

    @Override
    public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
        return SqlHelper.getObject(log, listObjs(queryWrapper, mapper));
    }
    public int count(Wrapper<T> queryWrapper) {

        return SqlHelper.retCount(getBaseMapper().selectCount(genWrapper((QueryWrapper<T>)queryWrapper)));
    }

    public List<T> list(Wrapper<T> queryWrapper) {
        return getBaseMapper().selectList(genWrapper((QueryWrapper<T>)queryWrapper));
    }

    public List<T> list() {
        return list(genWrapper(new QueryWrapper<T>()));
    }

    public <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper) {
        return getBaseMapper().selectPage(page, genWrapper((QueryWrapper<T>)queryWrapper));
    }

    public <E extends IPage<T>> E page(E page) {

        return page(page, genWrapper(new QueryWrapper<T>()));
    }

    public List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper) {
        return getBaseMapper().selectMaps(genWrapper((QueryWrapper<T>)queryWrapper));
    }

    public List<Map<String, Object>> listMaps() {
        return listMaps(genWrapper(new QueryWrapper<T>()));
    }

    public List<Object> listObjs(Wrapper<T> queryWrapper) {
        return listObjs(genWrapper((QueryWrapper<T>)queryWrapper), Function.identity());
    }

    public <V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
        return getBaseMapper().selectObjs(genWrapper((QueryWrapper<T>)queryWrapper)).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());
    }

    public <E extends IPage<Map<String, Object>>> E pageMaps(E page, Wrapper<T> queryWrapper) {
        return getBaseMapper().selectMapsPage(page, genWrapper((QueryWrapper<T>)queryWrapper));
    }

    /**
     * 取得此token的用户，单位权限的信息
     * @return
     */
    @Override
    public PermissionGrade getPermissionGrade(){
        String token = MDC.get(Constant.MDC_TOEKN);
        if (!(token==null || "".equals(token))){
            Object obj=null;
            if ((obj=sysCache.hget(Constant.USER_ORGANIZATION_ROLE,token))!=null){
                return (PermissionGrade)obj;
            }
        }
        return null;
    }

    /**
     * 由实体类生成查询条件
     * 并返回QueryWrapper
     * @param queryWrapper
     * @return
     */
    @Override
    public QueryWrapper<T> genWrapper(QueryWrapper<T> queryWrapper){
        return queryWrapper;
    }
}
